<?php
/**
 * RedXenon Framework
 * 
 * LICENSE
 * 
 * This source file is subject to the New BSD license that is bundled
 * with this package in the file LICENSE.txt
 * A copy of this license can be found in the world-wide-web at this URL:
 * http://www.redxenon.com/license/new-bsd-license.txt
 */

/* Database manager class */
require_once("RXDatabaseConnection.php");

/** 
 * RedXenon Database (RXQuery.php)
 * Class to manage Database Queries
 * 
 * @category RedXenon
 * @package RedXenon_Database
 * @copyright Copyright (c) 2011 Red Xenon (http://www.redxenon.com)
 * @version $Id: RXLogManagerCSV.php 1.0 2011-09-06 $ 
 */
class RXQuery{
	
	protected $connection;
	protected $debug;
	protected $query;	
	protected $queryType;
	protected $tables;
	protected $where;
	private $statement;
	
	public function __construct($connection = NULL, $query = NULL){
		$this->query = $query;
		
		if(!is_array($this->tables)){
			$this->tables = array();
		}
		
		if($connection){
			$this->connection = $connection;
		}else{
			$this->connection = new RXDatabaseConnection();
			
			try{
				$this->connection->connect();
			}catch(Exception $connectionException){
				printf("Connection Failed: %s", $connectionException->getMessage());
			}
		}
	}
	
	public function __destruct(){}
	
	public function startTransaction(){
		$this->connection->startTransaction();
	}
	
	public function commit(){
		$this->connection->commit();
	}
	
	public function rollback(){
		$this->connection->rollback();
	}
	
	/*
	public function prepareStatement(){
		if($this->query){
			$this->statement = $this->connection->prepareStatement($this->query);
		}else{
			throw new Exception("Statement cannot be prepared because there is no query to be prepared");
		}
	}
	
	public function runStatement($params){
		if($this->statement){
			if(is_array($params)){
				$types = "";
				foreach($params as $param){
					$type = getStatementParameterType($param);
					if($type){
						
					}
				}
			}else{
				
			}
		}
	}
	
	public function getStatementParameterType($parameter){
		if(is_double($parameter)){
			return "d";
		}else if(is_numeric($parameter)){
			return "i";
		}else if(is_bool($parameter)){
			return "i";
		}else if(is_string($parameter)){
			return "s";
		}else{
			return FALSE;
		}
	}
	*/
	
	/**
	 * @return String Query
	 */
	public function getQuery() {
		return $this->query;
	}

	/**
	 * @return String Query Type
	 */
	public function getQueryType() {
		return $this->queryType;
	}

	/**
	 * @return Array Table Names
	 */
	public function getTables() {
		return $this->tables;
	}

	/**
	 * @return String Where Statement
	 */
	public function getWhere() {
		return $this->where;
	}

	/**
	 * Loads a new value for the query
	 * @param String $query
	 */
	public function setQuery($query) {
		$this->query = $query;
	}

	/**
	 * Sets a new value for the Query Type
	 * @param String $queryType
	 */
	public function setQueryType($queryType) {
		$this->queryType = $queryType;
	}

	/**
	 * Sets a new array of tables
	 * @param Array $table
	 */
	public function setTable($tables) {
		$this->tables = $tables;
	}
	
	/**
	 * Adds a new pair of values Table - As to the schema
	 * @param String $tableName
	 * @param String $as
	 */
	public function addTable($tableName, $as = NULL){
		if(!is_array($this->tables)){
			$this->tables = array();
		}
		
		array_push($this->tables, array("tableName" => $tableName, "as" => $as));
	}

	/**
	 * Sets a new value for the Where Statement
	 * @param String $where
	 */
	public function setWhere($where) {
		$this->where = $where;
	}
	
	/**
	 * Adds a new Where Statement with the OR operand
	 * @param String $field - Field Name
	 * @param String $value - Value
	 * @param String $sign Sign to use as operando
	 * @param String $tableName
	 */
	public function addWhereOrStatement($field, $value, $sign, $tableName = NULL, $separator = "'"){
		$or = " OR ";
		if(!$this->where)
			$or = "";
		if($tableName){
			$this->where .= $or.$tableName.".".$field." ".$sign." '".$separator.$value.$separator."'";
		}else{
			$this->where .= $or.$field." ".$sign." '".$separator.$value.$separator."'";
		}
	}
	
	/**
	 * Adds a new Where Statement with the AND operand
	 * @param String $field - Field Name
	 * @param String $value - Value
	 * @param String $sign Sign to use as operando
	 * @param String $tableName
	 */
	public function addWhereAndStatement($field, $value, $sign, $tableName = NULL, $separator = "'"){
		$and = " AND ";
		if(!$this->where)
			$and = "";
		if($tableName){
			$this->where .= $and.$tableName.".".$field." ".$sign." ".$separator.$value.$separator;
		}else{
			$this->where .= $and.$field." ".$sign." ".$separator.$value.$separator;
		}
	}
	
	/**
	 * Makes a call to the Add Where And Statement with Different operand
	 * @param String $field - Field Name
	 * @param String $value - Value
	 * @param String $tableName
	 */
	public function addWhereAndStatementDifferent($field, $value, $tableName = NULL){
		$this->addWhereAndStatement($field, $value, "!=", $tableName);
	}
	
	/**
	 * Makes a call to the Add Where And Statement with Equals operand
	 * @param String $field - Field Name
	 * @param String $value - Value
	 * @param String $tableName
	 */
	public function addWhereAndStatementEquals($field, $value, $tableName = NULL){
		$this->addWhereAndStatement($field, $value, "=", $tableName);
	}
	
	/**
	 * Makes a call to the Add Where Or Statement with Different operand
	 * @param String $field - Field Name
	 * @param String $value - Value
	 * @param String $tableName
	 */
	public function addWhereOrStatementDifferent($field, $value, $tableName = NULL){
		$this->addWhereOrStatement($field, $value, "!=", $tableName);
	}
	
	/**
	 * Makes a call to the Add Where Or Statement with Equals operand
	 * @param String $field - Field Name
	 * @param String $value - Value
	 * @param String $tableName
	 */
	public function addWhereOrStatementEquals($field, $value, $tableName = NULL){
		$this->addWhereOrStatement($field, $value, "=", $tableName);
	}
	
	public function addWhereAndTableIntersection($tableOrigin, $fieldOrigin, $tableDestination, $fieldDestination){
		$this->addWhereAndStatement($fieldOrigin, $tableDestination.".".$fieldDestination, "=", $tableOrigin, "");
	}
	
	public function addWhereOrTableIntersection($tableOrigin, $fieldOrigin, $tableDestination, $fieldDestination){
		$this->addWhereOrStatement($fieldOrigin, $tableDestination.".".$fieldDestination, "=", $tableOrigin, "");
	}
	
	public function addWhereAndTableOdd($tableOrigin, $fieldOrigin, $tableDestination, $fieldDestination){		
		$this->addWhereAndStatement($fieldOrigin, $tableDestination.".".$fieldDestination, "!=", $tableOrigin, "");
	}
	
	public function addWhereOrTableOdd($tableOrigin, $fieldOrigin, $tableDestination, $fieldDestination){		
		$this->addWhereOrStatement($fieldOrigin, $tableDestination.".".$fieldDestination, "!=", $tableOrigin, "");
	}
	
	/**
	 * Adds a custom where with a combinator
	 * @param String $value
	 * @param String $combinator, AND, OR, ... 
	 */
	public function addWhere($value, $combinator = "AND"){
		$this->where .= " ".$combinator." ".$value;
	}
	
	public function exec(){
		
		if(@$_GET["debugRXDB"])
			echo "<br><strong>QUERY EXECUTED:</strong><br>".$this->query."<br><br>";
		
		if($this->query){
			$ret =  $this->connection->exec($this->query);
			unset($this->query);
			return $ret;
		}else{
			return FALSE;
		}
	}
	
	/**
	 * @return Error
	 */
	public function getError(){
		return $this->connection->getError();
	}
}
?>